package com.murong.ai.chat.component;

import ai.picovoice.porcupine.Porcupine;
import com.murong.ai.chat.domain.FlowCallService;
import com.murong.ai.chat.infrastructure.utils.PrintUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.TargetDataLine;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@Component
public class ListenToEnglishComponent {
    @Autowired
    FlowCallService flowCall;
    @Autowired
    private Porcupine porcupine;
    @Autowired
    private TargetDataLine microphone;
    @Autowired
    private AudioFormat audioFormat;

    @SneakyThrows
    public void startListening() {

        microphone.open(audioFormat);
        microphone.start();

        ByteBuffer captureBuffer = ByteBuffer.allocate(porcupine.getFrameLength() * 2); // 16-bit samples
        captureBuffer.order(ByteOrder.LITTLE_ENDIAN);
        PrintUtils.logLine("Listening for wake word...");
        byte[] tempBuffer = new byte[porcupine.getFrameLength() * 2];
        short[] pcm = new short[porcupine.getFrameLength()];

        try {
            while (true) {
                int bytesRead = microphone.read(tempBuffer, 0, tempBuffer.length);
                if (bytesRead > 0) {
                    captureBuffer.clear();
                    captureBuffer.put(tempBuffer);
                    captureBuffer.rewind();

                    for (int i = 0; i < porcupine.getFrameLength(); i++) {
                        pcm[i] = captureBuffer.getShort();
                    }

                    int result = porcupine.process(pcm);
                    if (result >= 0) {
                        flowCall.request("start");
                        break;
                    }
                }
            }
        }finally {
            microphone.stop();
            microphone.close();
            porcupine.delete();
        }
    }
}
